package com.way.capture.utils;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import androidx.exifinterface.media.ExifInterface;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import android.util.Pair;
import android.webkit.MimeTypeMap;

import com.way.capture.R;
import com.way.capture.data.DataInfo;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;

public class AppUtil {
    public static final String APP_ABSOLUTE_ROOT_PATH = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_MOVIES).getAbsolutePath();
    public static final String APP_SCREENSHOT_ABSOLUTE_ROOT_PATH = Environment
            .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath();
    //screenshot
    public static final String SCREENSHOT_FOLDER_NAME = "Screenshots";
    public static final String SCREENSHOT_FOLDER_PATH = new File(APP_SCREENSHOT_ABSOLUTE_ROOT_PATH,
            SCREENSHOT_FOLDER_NAME).getAbsolutePath();
    // videos folder, maybe not be needed
    public static final String VIDEOS_FOLDER_NAME = "ScreenRecord";
    public static final String VIDEOS_FOLDER_PATH = new File(APP_ABSOLUTE_ROOT_PATH,
            VIDEOS_FOLDER_NAME).getAbsolutePath();
    public static final String APP_FIRST_RUN = "app_first_run";
    public static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
    public static final String SCREEN_RECORD_SHARE_SUBJECT_TEMPLATE = "Screen record (%s)";
    private static final String TAG = "AppUtil";

    public static Pair<Integer, Integer> getVideoWidthHeight(String path) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(path);
            Bitmap bitmap = retriever.getFrameAtTime();

            int[] dimensions = new int[2];

            if (bitmap != null) {
                dimensions[0] = bitmap.getWidth() > 0 ? bitmap.getWidth() : 1;
                dimensions[1] = bitmap.getHeight() > 0 ? bitmap.getHeight() : 1;
            }
            Log.d(TAG, "getVideoWidthHeight: dimensions = " + dimensions);
            return new Pair<>(dimensions[0], dimensions[1]);
        } catch (Exception e) {
            Log.e(TAG, "getVideoWidthHeight: ", e);
            //e.printStackTrace();
        } finally {
            retriever.release();
        }
        return new Pair<>(Integer.MIN_VALUE, Integer.MIN_VALUE);
    }

    public static String getVideoDuration(String path) {
        String totalDuration = "00:00";
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(path);
            // 取得视频的长度(单位为毫秒)
            String time = retriever
                    .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            totalDuration = getVideoFormatTime(Integer.valueOf(time));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            retriever.release();
        }
        return totalDuration;
    }

    public static String getVideoFormatTime(int timeMs) {
        StringBuilder formatBuilder = new StringBuilder();
        Formatter formatter = new Formatter(formatBuilder, Locale.getDefault());
        int totalSeconds = timeMs / 1000;

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        formatBuilder.setLength(0);
        if (hours > 0) {
            return formatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
        } else {
            return formatter.format("%02d:%02d", minutes, seconds).toString();
        }
    }

    public static void showDetails(Activity activity, DataInfo dataInfo, int type) {
        String message = getDetails(activity, dataInfo, type);
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(R.string.image_info).setMessage(message).setPositiveButton(android.R.string.ok, null);
        builder.create().show();
    }

    public static String getDetails(Activity activity, DataInfo dataInfo, int type) {
        File file = new File(dataInfo.path);
        String length = android.text.format.Formatter.formatFileSize(activity, file.length());
        length = activity.getString(R.string.image_info_length, length);
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified()));
        time = activity.getString(R.string.image_info_time, time);
        String location = activity.getString(R.string.image_info_path, dataInfo.path);
        switch (type) {
            case DataInfo.TYPE_SCREEN_SHOT:
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(dataInfo.path, options);
                int height = options.outHeight;
                int width = options.outWidth;
                String size = activity.getString(R.string.image_info_size, width, height);

                return size + "\n" + length + "\n" + time + "\n" + location;
            case DataInfo.TYPE_SCREEN_RECORD:
//                ExifInterface exif = null;
//                if (AppUtil.exifSupported(App.getContext(), dataInfo)) {
//                    Log.d(TAG, "getDetails: exifSupported...");
//                    exif = ExifUtil.getExifInterface(App.getContext(), dataInfo);
//                }
//                Pair<Integer, Integer> pair =  retrieveDimensions(App.getContext(), exif, dataInfo);
                Pair<Integer, Integer> pair = getVideoWidthHeight(dataInfo.path);
                String sizeVideo = activity.getString(R.string.image_info_size, pair.first, pair.second);
                String duration = AppUtil.getVideoDuration(dataInfo.path);
                duration = activity.getString(R.string.image_info_duration, duration);
                return sizeVideo + "\n" + duration + "\n" + length + "\n" + time + "\n" + location;

        }
        return "";
    }

    public static Pair<Integer, Integer> retrieveDimensions(Context context, ExifInterface exif, DataInfo albumItem) {
        if (exif != null) {
            String height = String.valueOf(ExifUtil.getCastValue(exif, ExifInterface.TAG_IMAGE_LENGTH));
            String width = String.valueOf(ExifUtil.getCastValue(exif, ExifInterface.TAG_IMAGE_WIDTH));
            Log.d(TAG, "retrieveDimensions: size = " + width + "x" + height);
            return new Pair<>(Integer.valueOf(width), Integer.valueOf(height));
        }
        /*Exif not supported/working for this image*/
        return getVideoWidthHeight(albumItem.path);
    }

    public static void shareScreenshot(Context context, String path, int type) {
        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path)));
        String subjectDate = DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis()));
        switch (type) {
            case DataInfo.TYPE_SCREEN_SHOT:
                sharingIntent.setType("image/png");
                sharingIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate));
                break;
            case DataInfo.TYPE_SCREEN_RECORD:
                sharingIntent.setType("video/mp4");
                sharingIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(SCREEN_RECORD_SHARE_SUBJECT_TEMPLATE, subjectDate));
                break;
        }
        Intent chooserIntent = Intent.createChooser(sharingIntent, null);
        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(chooserIntent);
    }

    public static void shareMultipleScreenshot(Context context, String[] path, int type) {
        Intent sharingIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
        ArrayList<Uri> imageUris = new ArrayList<>();
        for (String p : path) {
            imageUris.add(Uri.fromFile(new File(p)));
        }
        sharingIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
        //sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path)));
        String subjectDate = DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis()));
        switch (type) {
            case DataInfo.TYPE_SCREEN_SHOT:
                sharingIntent.setType("image/png");
                sharingIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate));
                break;
            case DataInfo.TYPE_SCREEN_RECORD:
                sharingIntent.setType("video/mp4");
                sharingIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(SCREEN_RECORD_SHARE_SUBJECT_TEMPLATE, subjectDate));
                break;
        }
        Intent chooserIntent = Intent.createChooser(sharingIntent, null);
        chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(chooserIntent);
    }

    public static void deleteMultipleScreenshot(Context context, List<DataInfo> dataInfos) {
        String path[] = new String[dataInfos.size()];
        for (int i = 0; i < dataInfos.size(); i++) {
            DataInfo dataInfo = dataInfos.get(i);
            new File(dataInfo.path).delete();
            path[i] = dataInfo.path;
        }
        MediaScannerConnection.scanFile(context, path, null, null);
    }

    public static boolean hasAvailableSpace() {
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
        long bytesAvailable = stat.getBlockSizeLong() * stat.getAvailableBlocksLong();
        long megAvailable = bytesAvailable / 1048576;
        return megAvailable >= 100;
    }

    public static Uri getContentUri(Context context, int type, String path) {
        Uri uri;
        if (type == DataInfo.TYPE_SCREEN_RECORD) {
            uri = getContentUriForVideoFromMediaStore(context, path);
        } else {
            uri = getContentUriForImageFromMediaStore(context, path);
        }
        return uri;
    }

    private static Uri getContentUriForImageFromMediaStore(Context context, String path) {
        ContentResolver resolver = context.getContentResolver();
        //Uri photoUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        // to handle hidden images
        Uri photoUri = MediaStore.Files.getContentUri("external");
        Cursor cursor = resolver.query(photoUri,
                new String[]{BaseColumns._ID},
                MediaStore.MediaColumns.DATA + " = ?",
                new String[]{path}, null);
        if (cursor == null) {
            return Uri.parse(path);
        }
        cursor.moveToFirst();
        if (cursor.isAfterLast()) {
            cursor.close();
            // insert system media db
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, path);
            values.put(MediaStore.Images.Media.MIME_TYPE, getMimeType(path));
            return context.getContentResolver().insert(photoUri, values);
        } else {
            long id = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
            Uri uri = ContentUris.withAppendedId(photoUri, id);
            cursor.close();
            return uri;
        }
    }

    private static Uri getContentUriForVideoFromMediaStore(Context context, String path) {
        ContentResolver resolver = context.getContentResolver();
        //Uri videoUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        // to handle hidden videos
        Uri videoUri = MediaStore.Files.getContentUri("external");
        Cursor cursor = resolver.query(videoUri,
                new String[]{BaseColumns._ID},
                MediaStore.MediaColumns.DATA + " = ?",
                new String[]{path}, null);

        if (cursor == null) {
            return Uri.parse(path);
        }
        cursor.moveToFirst();
        if (cursor.isAfterLast()) {
            cursor.close();
            // insert system media db
            ContentValues values = new ContentValues();
            values.put(MediaStore.Video.Media.DATA, path);
            values.put(MediaStore.Video.Media.MIME_TYPE, getMimeType(path));
            return context.getContentResolver().insert(videoUri, values);
        } else {
            int imageId = cursor.getInt(cursor.getColumnIndex(BaseColumns._ID));
            Uri uri = ContentUris.withAppendedId(videoUri, imageId);
            cursor.close();
            return uri;
        }
    }

    public static String getMimeType(String path) {
        if (path == null) {
            return null;
        }
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(path);
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
    }

    public static String getMimeType(Context context, Uri uri) {
        return context.getContentResolver().getType(uri);
    }

    public static boolean exifSupported(Context context, DataInfo albumItem) {
        String mimeType = MediaType.getMimeType(context, AppUtil.getContentUri(context, albumItem.type, albumItem.path));
        return mimeType != null && MediaType.doesSupportExifMimeType(mimeType);
    }
}
